package com.jkt.rms.dataservice.impl;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Restrictions;

import com.jkt.rms.business.ResourceRole;
import com.jkt.rms.commons.utils.RMSException;
import com.jkt.rms.constants.IConstants;
import com.jkt.rms.dataservice.AbstractDataService;
import com.jkt.rms.dataservice.ResourceRoleDataService;


public class ResourceRoleDataServiceImpl extends AbstractDataService<ResourceRole> implements
ResourceRoleDataService {
	
	private static final Logger LOG = Logger.getLogger(ResourceRoleDataServiceImpl.class);
	@Override
	protected Class<ResourceRole> getReferenceClass() {
		return ResourceRole.class;
	}
	/**
	 * Save the role in DB
	 * @param ResourceRole
	 * @throws RMSException
	 */
	public void saveRole(ResourceRole ResourceRole) throws RMSException {
		try{
		save(ResourceRole);
		}catch(Exception ex){
			LOG.error("Error occur while saving roles:"+ex.getCause());
			throw new RMSException("error.application","error.application");
		}
	}
	/**
	 * update the Role
	 * @param ResourceRole
	 * @throws RMSException
	 */
	public void updateRole(ResourceRole ResourceRole) throws RMSException {
		try{
		saveOrUpdate(ResourceRole);
		}catch(Exception ex){
			LOG.error("Error occur while updating role:"+ex.getCause());
			throw new RMSException("error.application","error.application");
		}
	}

	/**
	 * Check if Role is already exist in DB.
	 * @param roleCode
	 * @param roleName
	 * @param id
	 * @return
	 */
	public boolean isRoleExist(String roleCode,String roleName, Long id) throws RMSException{
		List<ResourceRole> projRoleList = null;
		try{
		DetachedCriteria firstCriteria = DetachedCriteria.forClass(getReferenceClass());
		DetachedCriteria secondCriteria = DetachedCriteria.forClass(getReferenceClass());
			if(id != null && (!id.equals(IConstants.EMPTY_STRING))) {
				firstCriteria.add(Expression.ne(ResourceRole.PROP_RESOURCE_ROLE_ID, id));
				secondCriteria.add(Expression.ne(ResourceRole.PROP_RESOURCE_ROLE_ID, id));
			}
			if(roleCode != null && (!roleCode.equals(IConstants.EMPTY_STRING))) {
				firstCriteria.add(Restrictions.eq(ResourceRole.PROP_ROLE_CODE, roleCode.trim()));
				projRoleList = findByCriteria(firstCriteria);
				if(projRoleList.isEmpty()) {
					if(roleName != null && (!roleName.equals(IConstants.EMPTY_STRING))) {
						secondCriteria.add(Restrictions.eq(ResourceRole.PROP_ROLE_NAME, roleName.trim()));
						projRoleList = findByCriteria(secondCriteria);
					}
				} else {
					return true;
				}
		} else if(roleCode != null && (!roleCode.equals(IConstants.EMPTY_STRING))) {
			firstCriteria.add(Restrictions.eq(ResourceRole.PROP_ROLE_CODE, roleCode.trim()));
			projRoleList = findByCriteria(firstCriteria);
			if(projRoleList.isEmpty()) {
				if(roleName != null && (!roleName.equals(IConstants.EMPTY_STRING))) {
					secondCriteria.add(Restrictions.eq(ResourceRole.PROP_ROLE_NAME, roleName.trim()));
					projRoleList = findByCriteria(secondCriteria);
				}
			} else {
				return true;
			}
		}	
		}catch(Exception ex){
			LOG.error("Error occur while checking the duplicate Project Roles"+ex.getCause());
			throw new RMSException("error.application","error.application");
		}
		return !projRoleList.isEmpty();
	}
	/**
	 * Search the Roles based on search criteria.
	 * @param ResourceRole
	 * @return
	 */
	public List<ResourceRole> findByCriteria(ResourceRole ResourceRole) throws RMSException {
		DetachedCriteria criteria = DetachedCriteria.forClass(getReferenceClass());
		try{
		if(ResourceRole != null) {
			if(ResourceRole.getRoleCode() != null && (!ResourceRole.getRoleCode().equals(IConstants.EMPTY_STRING))) {
				criteria.add(Expression.like(ResourceRole.PROP_ROLE_CODE, ResourceRole.getRoleCode().trim() + "%"));
			}
			if(ResourceRole.getRoleName() != null && (!ResourceRole.getRoleName().equals(IConstants.EMPTY_STRING))) {
				criteria.add(Expression.like(ResourceRole.PROP_ROLE_NAME, ResourceRole.getRoleName().trim() + "%"));
				criteria.add(Expression.like(ResourceRole.PROP_STATUS, IConstants.STATUS_YES));
			}

		}
		}catch(Exception ex){
			LOG.error("Error occur while find Project Role by criteria:"+ex.getCause());
			throw new RMSException("error.application","error.application");
		}
		return findByCriteria(criteria);
	}
	
	/**
	 * find the role in DB based upon project_role_id
	 */
	public ResourceRole findById(Long id) throws RMSException{
		DetachedCriteria criteria = DetachedCriteria.forClass(getReferenceClass());
		ResourceRole ResourceRole = null;
		try {
			if(id != null) {
				criteria.add(Expression.like(ResourceRole.PROP_RESOURCE_ROLE_ID, id));
			}
			List<ResourceRole> findByCriteria = findByCriteria(criteria);
			ResourceRole = findByCriteria.get(0);
		} catch (Exception ex) {
			LOG.error("Error occur while find Project Role by ID"+ex.getCause());
			throw new RMSException("error.application","error.application");
		}
		return ResourceRole;
	}
	
	/**
	 * this method return the list of all active role from DB.
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<ResourceRole> getActiveRolesList() throws RMSException{
	List<ResourceRole> projRoleList=null;
		try{
			projRoleList=getSession().createQuery("from ResourceRole v where v.status = 'Y'").list();
		}catch(Exception ex){
			LOG.error("Error occur while getting Project Roles:"+ex.getCause());
			throw new RMSException("error.application","error.application");
			}
		return projRoleList;
		}
}
